package com.hhd.flow.controller;

import cn.hutool.json.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.hhd.flow.engine.vo.FlowModel;
import com.hhd.flow.vo.Result;
import com.hhd.flow.engine.FlowEngine;
import com.hhd.flow.engine.utils.CommonUtils;
import com.hhd.flow.entity.FlowProcessDefinition;
import com.hhd.flow.service.IFlowProcessDefinitionService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@RequestMapping("/flow")
@RestController
public class FlowDefinitionController {
    @Autowired
    FlowEngine flowEngine;

    @GetMapping("/getFlowDefinitionsByFormType")
    public Result getFlowDefinitionsByFormType(String formType) {
        return Result.ok(flowEngine.getFlowProcessDefinitionService()
                .lambdaQuery().eq(FlowProcessDefinition::getFormType, formType)
                .list());
    }

    @PostMapping("/saveFlowModel")
    public Result saveFlowModel(@RequestBody FlowProcessDefinition flowProcessDefinition) {
        resolveDefinition(flowProcessDefinition);
        if (CommonUtils.isEmpty(flowProcessDefinition.getVersion())) {
            flowProcessDefinition.setVersion(0);
        } else {
            flowProcessDefinition.setVersion(flowProcessDefinition.getVersion() + 1);
        }
        IFlowProcessDefinitionService flowProcessDefinitionService = flowEngine.getFlowProcessDefinitionService();
        flowProcessDefinitionService.saveOrUpdate(flowProcessDefinition);

        if (flowProcessDefinition.getEnable()) {
            flowProcessDefinitionService.lambdaUpdate()
                    .eq(FlowProcessDefinition::getEnable, true)
                    .eq(FlowProcessDefinition::getFormType, flowProcessDefinition.getFormType())
                    .ne(FlowProcessDefinition::getId, flowProcessDefinition.getId())
                    .set(FlowProcessDefinition::getEnable, false).update();
        } else {
            Integer count = flowProcessDefinitionService.lambdaQuery()
                    .eq(FlowProcessDefinition::getFormType, flowProcessDefinition.getFormType())
                    .eq(FlowProcessDefinition::getEnable, true)
                    .count();
            if (count <= 0) {
                flowProcessDefinitionService.lambdaUpdate()
                        .eq(FlowProcessDefinition::getId, flowProcessDefinition.getId())
                        .set(FlowProcessDefinition::getEnable, true)
                        .update();
            }
        }

        return Result.ok();
    }

    private static void resolveDefinition(FlowProcessDefinition flowProcessDefinition) {
        FlowModel flowModel = FlowModel.forString(flowProcessDefinition.getModel());
        flowProcessDefinition.setModel(null);
        if (CommonUtils.isEmpty(flowProcessDefinition.getId())) {
            flowProcessDefinition.setId(IdWorker.getIdStr());
        }

        flowModel.getJsonModel().put("id", flowProcessDefinition.getId());
        flowModel.getJsonModel().put("formType", flowProcessDefinition.getFormType());
        flowModel.getJsonModel().put("titleFormula", flowProcessDefinition.getTitleFormula());
        flowModel.getJsonModel().put("titleFormulaText", flowProcessDefinition.getTitleFormulaText());
        flowModel.getJsonModel().put("beforeListeners", flowProcessDefinition.getBeforeListeners());
        flowModel.getJsonModel().put("afterListeners", flowProcessDefinition.getAfterListeners());

        flowProcessDefinition.setModel(flowModel.getModelString());
    }


    @DeleteMapping("/removeById")
    public Result removeById(String id) {
        flowEngine.getFlowProcessDefinitionService().removeById(id);
        return Result.ok();
    }
}
